package com.sservice.web.controller.admin;

import com.sservice.common.*;
import com.sservice.urp.dao.IComDao;
import com.sservice.model.dao.IGoodsDao;
import com.sservice.model.dao.OrderPaperMapper;
import com.sservice.model.vo.PurchaseOrderVo;
import com.sservice.urp.entity.Com;
import com.sservice.urp.entity.User;
import com.sservice.urp.vo.UserVo;
import com.sservice.service.service.*;
import com.sservice.web.common.*;
import com.sservice.base.entity.dto.BaseResult;
import com.sservice.base.entity.dto.ListResult;
import com.sservice.base.entity.dto.Pagination;
import com.sservice.model.entity.*;
import com.sservice.web.utils.PdfUtils;
import com.lowagie.text.DocumentException;
import freemarker.template.TemplateException;
import org.apache.commons.collections.map.HashedMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

@Controller
@RequestMapping("/admin/purchaseOrder")
public class PurchaseOrderController {
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private PurchaseOrderService service;
    @Autowired
    private IAdvanceReceiptService arMapper;
    @Autowired
    private PurchaseService purchaseService;
    @Autowired
    private IPurchaseOrderPaperService purchaseOrderPaperService;
    @Autowired
    private PurchaseOrderLogService serviceLog;
    @Autowired
    private IOrderPaperService orderPaperService;
    @Autowired
    private OrderPaperMapper orderPaperMapper;
    @Autowired
    private IClienteleService clienteleService;
    @Autowired
    private IGoodsService goodsService;
    @Autowired
    private IGoodsDao goodsDao;
    @Autowired
    private IComDao comMapper;

    @Autowired
    private ExportService exportService;


    @RequestMapping(value = "/{id}-{clientleName}.pdf")
    public OutputStream toPdf(PurchaseOrder order, String id, String clientName, HttpSession session, HttpServletResponse response) throws DocumentException, TemplateException, IOException {
        OrderPaper op = new OrderPaper();
        op.setOrderId(String.valueOf(order.getId()));
        op.setOrderType("1");
        OrderPaper op1 = orderPaperMapper.selectByOrderIdAndOrderType(op);
        ClassPathResource resource = new ClassPathResource("paper/tpl.ftl");
        Map<Object, Object> o = new HashMap<Object, Object>();
        String body = new String(op1.getPaper());

        o.put("body", body);
        String path_ = resource.getURL().toString().replace("paper/tpl.ftl", "");
        return PdfUtils.generateToServletOutputStream(path_.replace("file:" + (path_.indexOf("usr/") > -1 ? "" : "/"), ""), "paper/tpl.ftl",
                resource.getURL().toString().replace("paper/tpl.ftl", ""), o, response);
    }

    @RequestMapping(value = "/back/{id}-{clientleName}.pdf")
    public OutputStream backtoPdf(PurchaseOrder order, String id, String clientName, HttpSession session, HttpServletResponse response) throws DocumentException, TemplateException, IOException {
        OrderPaper op = new OrderPaper();
        op.setOrderId(String.valueOf(order.getId()));
        op.setOrderType("4");
        OrderPaper op1 = orderPaperMapper.selectByOrderIdAndOrderType(op);
        ClassPathResource resource = new ClassPathResource("paper/tpl.ftl");
        Map<Object, Object> o = new HashMap<Object, Object>();
        String body = new String(op1.getPaper());

        o.put("body", body);
        String path_ = resource.getURL().toString().replace("paper/tpl.ftl", "");
        return PdfUtils.generateToServletOutputStream(path_.replace("file:" + (path_.indexOf("usr/") > -1 ? "" : "/"), ""), "paper/tpl.ftl",
                resource.getURL().toString().replace("paper/tpl.ftl", ""), o, response);
    }

    @SameUrlData
    @ResponseBody
    @RequestMapping(value = "/save-paper", method = RequestMethod.POST)
    public BaseResult savePaper(OrderPaper op, HttpSession session, HttpServletRequest request) {
        User user = (User) session.getAttribute(Constants.USER);
        if (op.getOrderType() == null) {
            op.setOrderType("1"); // 采购合同
        }
        OrderPaper op_res = orderPaperMapper.selectByOrderIdAndOrderType(op);
        int res = 0;
        if (op_res == null) {
            op.setUserId(String.valueOf(user.getId()));
            if (op.getPath() != null) {
                serviceLog.log("上传合同", request, Integer.valueOf(op_res.getOrderId()));
            } else {
                serviceLog.log("4".equals(op.getOrderType()) ? "保存退款申请函" : "保存合同", request, Integer.valueOf(op.getOrderId()));
            }
            res = orderPaperService.insertSelective(op);
        } else {
            op.setId(op_res.getId());
            if (op.getSingle() != null) {
                serviceLog.log("上传单签合同:" + op.getSingle(), request, Integer.valueOf(op_res.getOrderId())); //
                op.setSingle(op.getSingle() + ',' + op_res.getSingle());
            }
            if (op.getPath() != null) {
                serviceLog.log("上传合同:" + op.getPath(), request, Integer.valueOf(op_res.getOrderId())); //
                op.setPath(op.getPath() + ',' + op_res.getPath());
            }
            ;
            if (op.getCouple() != null) {
                serviceLog.log("上传双签合同:" + op.getCouple(), request, Integer.valueOf(op_res.getOrderId())); //
                op.setCouple(op.getCouple() + ',' + op_res.getCouple());
            }
            ;
            res = orderPaperService.updateByPrimaryKeySelective(op);
        }
        return new BaseResult(true, res);
    }


    /***
     * 分页查询
     * @param arg
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/query", method = RequestMethod.GET)
    public ListResult query(PurchaseOrderVo arg, HttpSession session, boolean isExport) {
        if (isExport) {
            arg.setPage(0);
            arg.setSize(Integer.MAX_VALUE);
            List<PurchaseOrderVo> list_order = service.queryByPage(arg);
            return new ListResult(true, list_order);
        }
        List<PurchaseOrderVo> list_order = service.queryByPage(arg);
        int total = service.queryCount(arg);
        Pagination page = new Pagination(arg.getPage(), total, arg.getSize());
        ListResult res = new ListResult(true, list_order);
        res.setPage(page);
        return res;
    }

    /***
     * 授权查看
     * @param arg
     * @param session
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/queryWithAuth", method = RequestMethod.GET)
    public ListResult queryWithAuth(PurchaseOrderVo arg, HttpSession session, boolean isExport) {

        UserVo user = (UserVo) session.getAttribute(Constants.USER);
        Boolean isManger = false;
        if (1 == user.getId()) {
            isManger = true;
        }
        if (!isManger) { //运营账户判断判断
            Goods g = new Goods();
            g.setOperatorId(String.valueOf(user.getId()));
            List<Goods> list = goodsDao.queryFindInSet(g);
            if (!isManger && 0 == list.size()) {
                return new ListResult(false, "非运营或超级管理员角色账号，无权访问!", 403);
            }
            List<String> lstr = new ArrayList<String>();
            for (Goods item : list) {
                if (("," + item.getOperatorId() + ",").indexOf("," + user.getId() + ",") > -1) {
                    lstr.add(String.valueOf(item.getId()));
                }
            }
            if (lstr.size() > 0) {
                arg.setList(lstr);
            }
        }
        if (isExport) {
            arg.setPage(0);
            arg.setSize(Integer.MAX_VALUE);
            List<PurchaseOrderVo> list_order = service.queryByPage(arg);
            return new ListResult(true, list_order);
        }

//        List<PurchaseVo> list_order = service.queryByPage(arg);
        List<PurchaseOrderVo> list_order = service.queryByPage(arg);
        int total = service.queryCount(arg);
        Pagination page = new Pagination(arg.getPage(), total, arg.getSize());
        ListResult res = new ListResult(true, list_order);
        res.setPage(page);
        return res;
    }

    //
    @ResponseBody
    @RequestMapping(value = "/queryApplyPay", method = RequestMethod.GET)
    public ListResult queryApplyPay(PurchaseOrderVo arg, HttpSession session) {
        arg.setApplyPay("1");
        if (arg.getPayStatus() == null) {
            arg.setPayStatus("01");
        }

        List<PurchaseOrderVo> list_order = service.queryByPage(arg);
        int total = service.queryCount(arg);
        Pagination page = new Pagination(arg.getPage(), total, arg.getSize());
        ListResult res = new ListResult(true, list_order);
        res.setPage(page);
        return res;
    }


    @ResponseBody
    @RequestMapping(value = "/print", method = RequestMethod.GET)
    public BaseResult print(PurchaseOrder arg, HttpSession session) {
        BaseResult res = new BaseResult(true, 1);
        return res;
    }

    @ResponseBody
    @RequestMapping(value = "/getOrderPaper", method = RequestMethod.GET)
    public BaseResult getOrderPaper(PurchaseOrder arg, HttpSession session) {

        PurchaseOrder po = service.selectByPrimaryKey(arg.getId());
        if ("1".equals(po.getCheckStatus())) {
            OrderPaper op = new OrderPaper();
            op.setOrderType("1");
            op.setOrderId(String.valueOf(arg.getId()));
            OrderPaper pop = orderPaperMapper.selectByOrderIdAndOrderType(op);
            if (pop != null) {
                pop.setPaper_(new String(pop.getPaper()));
            }
            return new BaseResult(true, pop);
        } else {
            User user = (User) session.getAttribute(Constants.USER);
            if (user.getId() == 1) {
                return new BaseResult(false, "超级管理员不能保存合同", 403);
            }
            Com com = comMapper.selectByPrimaryKey(user.getComid());
            Purchase purchase = purchaseService.selectByPrimaryKey(Integer.valueOf(po.getPurchaseId()));
            Goods goods = goodsService.selectByPrimaryKey(Integer.valueOf(po.getGoodsId()));
            Map<String, Object> map = new HashedMap();
            OrderPaper op = new OrderPaper();
            op.setOrderType("1");
            op.setOrderId(String.valueOf(arg.getId()));
            OrderPaper pop = orderPaperMapper.selectByOrderIdAndOrderType(op);
            if (pop != null) {
                //pop.setPaper_(new String(pop.gePaper()));
                map.put("paper_", new String(pop.getPaper()));

            }
            map.put("number", po.getNumber());
            Clientele clientele = clienteleService.selectByPrimaryKey(Integer.valueOf(po.getClienteleId()));
            map.put("buyer", com.getName()); // 需方
            map.put("com", clientele.getComName()); // 供方
            map.put("no", po.getNo());
            map.put("time_place", new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + " 上海");
            map.put("price", po.getCurrentPrice());
            map.put("money", po.getTotal());
            map.put("goodsName", goods.getName());
            map.put("unit", goods.getUnit());
            map.put("priceUnit", purchase.getUnitPrice());
            map.put("contractValue", PrintContract.change(po.getTotal().doubleValue()));
            map.put("qualityRequire", purchase.getQualitySpec()); //品质
            map.put("packSpec", purchase.getPackSpec()); //包装规格额
            map.put("quality", purchase.getQualityStandard());
            map.put("storeName", po.getStoreName());
            map.put("deliverStart", po.getDeliverStart());
            map.put("deliverEnd", po.getDeliverEnd());
            map.put("days", po.getDays());
            map.put("daysFlag", po.getDaysFlag());
            map.put("deliverMethod", po.getDeliverMethod());
            map.put("storeTime", po.getStoreTime());
            map.put("payTime", po.getPayTime());
            map.put("comAddress", clientele.getAddress());
            map.put("comTel", clientele.getTel());
            map.put("comFax", clientele.getFax());
            map.put("comBank", clientele.getBank());
            map.put("comBankAccount", clientele.getBankAccount());
            map.put("buyerAddress", com.getAddress());
            map.put("buyerTel", com.getTel());
            map.put("buyerFax", com.getFax());
            return new BaseResult(true, map);
        }
    }

    /**
     * 退款申请函
     *
     * @param arg
     * @param session
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/getBackPaper", method = RequestMethod.GET)
    public BaseResult getBackPaper(PurchaseOrder arg, HttpSession session) {

        PurchaseOrder po = service.selectByPrimaryKey(arg.getId());
        User user = (User) session.getAttribute(Constants.USER);
        if (user.getId() == 1) {
            return new BaseResult(false, "超级管理员不能打印退款申请函 ", 403);
        }
        OrderPaper op = new OrderPaper();
        op.setOrderType("4");
        op.setOrderId(String.valueOf(arg.getId()));
        OrderPaper pop = orderPaperMapper.selectByOrderIdAndOrderType(op);
        if (pop != null) {
            pop.setPaper_(new String(pop.getPaper()));
            return new BaseResult(true, pop);
        }

        Com com = comMapper.selectByPrimaryKey(user.getComid());
        Map<String, Object> map = new HashedMap();
        Clientele clientele = clienteleService.selectByPrimaryKey(Integer.valueOf(po.getClienteleId()));
        map.put("buyer", com.getName()); // 需方
        map.put("provider", clientele.getComName()); // 供方
        map.put("money", Arith.sub(Arith.sub(po.getActualReceiveTotal().doubleValue(),
                Arith.mul(po.getCurrentPrice().doubleValue(),
                        po.getNumberActualReceive().doubleValue())), po.getBackTotal().doubleValue()));
        map.put("user", user.getName());
        map.put("phone", user.getPhone());
        return new BaseResult(true, map);
    }


    @SameUrlData
    @ResponseBody
    @RequestMapping(value = "/create", method = RequestMethod.POST)
    public BaseResult create(PurchaseOrder arg, HttpSession session, HttpServletRequest request) {
        User user = (User) session.getAttribute(Constants.USER);
        arg.setUserName(user.getName());
        arg.setUserId(String.valueOf(user.getId()));
        arg.setType("1"); // 后台用户下单
        Clientele clientele = clienteleService.selectByPrimaryKey(Integer.valueOf(arg.getClienteleId()));
        if (!("1".equals(clientele.getSupplierCheckStatus()) && "1".equals(clientele.getStatus()))) {
            return new BaseResult(false, "供应商未审核通过,不能下单!", 403);
        }
        Object list_order = service.createOrder(arg);
        if (list_order instanceof String) {
            return new BaseResult(false, list_order.toString(), 403);
        }
        serviceLog.log("创建" + arg.getReason(), request, arg.getId());

        BaseResult res = new BaseResult(true, list_order);
        return res;

    }

    @ResponseBody
    @RequestMapping(value = "/get", method = RequestMethod.GET)
    public BaseResult get(PurchaseOrder arg, HttpSession session) {
        PurchaseOrder list_order = service.selectByPrimaryKey(arg.getId());
        BaseResult res = new BaseResult(true, list_order);
        return res;
    }

    @ResponseBody
    @RequestMapping(value = "/detail", method = RequestMethod.GET)
    public BaseResult detail(PurchaseOrder arg, HttpSession session) {
        Map map = new HashMap();

        PurchaseOrder list_order = service.selectByPrimaryKey(arg.getId());
        Purchase purchase = purchaseService.selectByPrimaryKey(Integer.valueOf(list_order.getPurchaseId()));
        map.put("order", list_order);
        map.put("purchase", purchase);

        BaseResult res = new BaseResult(true, map);
        return res;
    }


    @ResponseBody
    @RequestMapping(value = "/update", method = RequestMethod.POST)
    public BaseResult update(PurchaseOrder arg, HttpServletRequest request) {
        PurchaseOrder purchase = service.selectByPrimaryKey(arg.getId());
        arg.setCheckStatus(null); // 拒绝通过update进行审核
        arg.setCheckStatus(purchase.getCheckStatus());
        if (arg.getCurrentPrice() != null && arg.getCurrentPrice().compareTo(BigDecimal.valueOf(0.0)) == 1) { //  采购价格修改
            arg.setTotal(arg.getCurrentPrice().multiply(purchase.getNumber()));
        }
        Object list_order = service.updateWidthPrice(arg);
        if (list_order instanceof String) {
            return new BaseResult(false, list_order.toString(), 403);
        }
        int lo = Integer.valueOf(list_order.toString());
        if (lo > 0) {
            Map<String, Object> res = CompareObject.contrastObj(arg, purchase);
            serviceLog.log(res, request, arg.getId());
        }
        BaseResult res = new BaseResult(true, list_order);
        return res;
    }

    @Transactional
    @ResponseBody
    @RequestMapping(value = "/refuse", method = RequestMethod.POST)
    public BaseResult refuse(PurchaseOrder arg, HttpServletRequest request) {
        PurchaseOrder po = new PurchaseOrder();
        po.setId(arg.getId());
        po.setCheckStatus("2");
        po.setReason(arg.getReason());
        int list_order = service.updateByPrimaryKeySelective(po);
        if (list_order > 0) {
            release(String.valueOf(po.getId())); // 释放占有资源
            serviceLog.log("审核拒绝," + arg.getReason(), request, arg.getId());
        }
        BaseResult res = new BaseResult(true, list_order);
        return res;
    }


    @SameUrlData
    @ResponseBody
    @RequestMapping(value = "/allow", method = RequestMethod.POST)
    public BaseResult allow(PurchaseOrder arg, HttpServletRequest request) {
        OrderPaper op = new OrderPaper();
        op.setOrderId(String.valueOf(arg.getId()));
        op.setOrderType("1");
        OrderPaper op1 = orderPaperMapper.selectByOrderIdAndOrderType(op);
        if (op1 == null) {
            return new BaseResult(false, "请先编辑保存合同!", 403);
        }else if(op1.getPaper()==null){
            return new BaseResult(false, "请先编辑保存合同!", 403);
        }
        PurchaseOrder po = new PurchaseOrder();
        po.setId(arg.getId());
        po.setCheckStatus("1");
        po.setReason(arg.getReason());
        po.setStatus("1"); // 订单执行中

        Object list_order = service.updateByPrimaryKeySelective(po);
        if (list_order instanceof String) {
            return new BaseResult(false, list_order.toString(), 403);
        }
        int lo = Integer.valueOf(list_order.toString());
        if (lo > 0) {
            serviceLog.log("审核通过", request, arg.getId());
        }
        BaseResult res = new BaseResult(true, list_order);
        return res;
    }

    /***
     *  申请退款
     * @param arg
     * @param request
     * @return
     */
    @SameUrlData
    @ResponseBody
    @RequestMapping(value = "/applyBack/{id}", method = RequestMethod.GET)
    public BaseResult applyBack(PurchaseOrder arg, HttpServletRequest request) {

        PurchaseOrder po = new PurchaseOrder();
        po.setId(arg.getId());
        po.setApplyBack("1");
        Object list_order = service.updateByPrimaryKeySelective(po);
        if (list_order instanceof String) {
            return new BaseResult(false, list_order.toString(), 403);
        }
        int lo = Integer.valueOf(list_order.toString());
        if (lo > 0) {
            serviceLog.log("申请退款", request, arg.getId());
        }
        return new BaseResult(true, list_order);
    }

    /***
     * 转化预付款单
     * @param arg
     * @param request
     * @return
     */
    @SameUrlData
    @ResponseBody
    @RequestMapping(value = "/transfer/{id}", method = RequestMethod.POST)
    public BaseResult transfer(PurchaseOrder arg, HttpServletRequest request) {
        User user = (User) request.getSession().getAttribute(Constants.USER);
        PurchaseOrder po = new PurchaseOrder();
        po.setId(arg.getId());
        po.setApplyBack("2"); // 完全退款
        PurchaseOrder purchaseOrder = service.selectByPrimaryKey(arg.getId());
        AdvanceReceipt ar = new AdvanceReceipt();
        BigDecimal total = purchaseOrder.getActualReceiveTotal()
                .subtract(purchaseOrder.getCurrentPrice().multiply(purchaseOrder.getNumberActualReceive()));
//        ar.setTotalDeposit(total.subtract(purchaseOrder.getBackTotal())); //
        ar.setTotalDeposit(total); //
        ar.setClienteleId(purchaseOrder.getClienteleId());
        ar.setPayTime(new Date());
        ar.setPayType("4"); // 退款
        ar.setType("2");
        ar.setRemark("采购订单退款：" + purchaseOrder.getNo());
        ar.setOperator(String.valueOf(user.getId()));
        ar.setUnitCode(purchaseOrder.getUnitCode());
        arMapper.insertSelective(ar);
        Object list_order = service.updateByPrimaryKeySelective(po);
        int lo = Integer.valueOf(list_order.toString());
        if (lo > 0) {
            serviceLog.log("转化预付款单退款：" + ar.getTotalDeposit(), request, arg.getId());
        }
        return new BaseResult(true, list_order);
    }

    /***
     * 现金退款
     * @param arg
     * @param request
     * @return
     */
    @SameUrlData
    @Transactional
    @ResponseBody
    @RequestMapping(value = "/backMoney", method = RequestMethod.POST)
    public BaseResult backMoney(PurchaseOrder arg, HttpServletRequest request) {
        PurchaseOrder po1 = service.selectByPrimaryKey(arg.getId());
        PurchaseOrder po = new PurchaseOrder();
        po.setId(arg.getId());
        po.setBackTotal(arg.getBackTotal().add(po1.getBackTotal()));
        if (Double.compare(po.getBackTotal().doubleValue(),
                Arith.sub(po1.getActualReceiveTotal().doubleValue(),
                        Arith.mul(po1.getNumberActualReceive().doubleValue(), po1.getCurrentPrice().doubleValue()))) == 0) {
            po.setApplyBack("2"); // 已退款
        }
        Object list_order = service.updateByPrimaryKeySelective(po);
        AdvanceReceipt advanceReceipt = new AdvanceReceipt();
        advanceReceipt.setClienteleId(po1.getClienteleId());
        advanceReceipt.setUnitCode(po1.getUnitCode());
        advanceReceipt.setTotalDeposit(arg.getBackTotal());
        advanceReceipt.setOrderId(String.valueOf(po1.getId()));
        advanceReceipt.setRemark("采购订单现金退款");
        advanceReceipt.setNo(po1.getNo());
        advanceReceipt.setType("5"); // 采购退款
        User user = (User) request.getSession().getAttribute(Constants.USER);
        advanceReceipt.setOperator(String.valueOf(user.getId()));
        arMapper.insertSelective(advanceReceipt);
        if (list_order instanceof String) {
            return new BaseResult(false, list_order.toString(), 403);
        }
        int lo = Integer.valueOf(list_order.toString());
        if (lo > 0) {
            serviceLog.log("现金退款：" + arg.getBackTotal(), request, arg.getId());
        }
        return new BaseResult(true, list_order);
    }

    @SameUrlData
    @ResponseBody
    @RequestMapping(value = "/applyPay", method = RequestMethod.POST)
    public BaseResult applyPay(PurchaseOrder arg, HttpServletRequest request) {
        PurchaseOrder purchase = service.selectByPrimaryKey(arg.getId());
        if (!purchase.getCheckStatus().equals("1")) {
            return new BaseResult(false, "订单非审核通过状态,不能申请付款", 403);
        }
        arg.setApplyPay("1");
        int list_order = service.updateByPrimaryKeySelective(arg);
        if (list_order > 0) {
            serviceLog.log("申请付款", request, arg.getId());
        }
        return new BaseResult(true, list_order);
    }

    /**
     * 终止订单执行
     *
     * @param request
     * @return
     */
    @SameUrlData
    @ResponseBody
    @RequestMapping(value = "/end", method = RequestMethod.POST)
    public BaseResult end(PurchaseOrder arg, HttpServletRequest request) {
        PurchaseOrder purchase2 = service.selectByPrimaryKey(arg.getId());
        if (purchase2.getApplyPayTotal().compareTo(BigDecimal.valueOf(0.0)) != 0) { ///付款申请单已完全付款
            return new BaseResult(false, "含有未实际付款的采购付款申请单，不能终止执行", 403);
        }
        if (purchase2.getCheckStatus().equals("1") && purchase2.getPayStatus().equals("0")
                && Double.compare(purchase2.getNumberActualReceive().doubleValue(), 0.0) == 0 &&
                Double.compare(purchase2.getNumberReceiving().doubleValue(), 0.0) == 0
                ) {
            arg.setStatus("2");
        } else {
//            订单状态:0未执行，1执行中，2终止执行，3强制执行完毕，4执行完毕
            return new BaseResult(false, "未审核、未付款、已收货、收货中的订单不能执行完毕!", 403);
        }
        int list_order = service.updateByPrimaryKeySelective(arg);
        if (list_order > 0) {
            release(String.valueOf(arg.getId())); // 释放占有资源
            serviceLog.log("终止执行", request, arg.getId());
        }
        return new BaseResult(true, list_order);
    }

    private void release(String orderId) {
        PurchaseOrder purchaseOrder = service.selectByPrimaryKey(Integer.valueOf(orderId));
        Purchase purchase = purchaseService.selectByPrimaryKey(Integer.valueOf(purchaseOrder.getPurchaseId()));
        Purchase purchase1 = new Purchase();
        purchase1.setId(purchase.getId());
        purchase1.setNumberCharging(purchase.getNumberCharging().subtract(purchaseOrder.getNumber()));
        purchase1.setNumber(purchase.getNumber().add(purchaseOrder.getNumber()));
        purchaseService.updateByPrimaryKeySelective(purchase1);

    }

    /**
     * 强制执行完毕
     *
     * @param arg
     * @param request
     * @return
     */
    @SameUrlData
    @ResponseBody
    @RequestMapping(value = "/forceEnd", method = RequestMethod.POST)
    public BaseResult forceEnd(PurchaseOrder arg, HttpServletRequest request) {

        Object list_order = service.forceEnd(arg);
        if (list_order instanceof String) {
            return new BaseResult(false, ((String) list_order).toString(), 403);
        }
        int list_order_res = (int) list_order;
        if (list_order_res > 0) {
            serviceLog.log("强制执行完毕", request, arg.getId());
        }
        return new BaseResult(true, list_order);
    }

    /**
     * 导出采购订单功能
     *
     * @param arg
     * @param session
     * @return
     */
    @SameUrlData
    @RequestMapping(value = "/exportWithAuth", method = RequestMethod.GET)
    public OutputStream export(PurchaseOrderVo arg, HttpSession session, HttpServletResponse response, HttpServletRequest request) throws IOException {
        ListResult lr = queryWithAuth(arg, session, true);
        List<PurchaseOrderVo> list = (List<PurchaseOrderVo>) lr.getList();
        ServletOutputStream outputStream = response.getOutputStream();
        response.setContentType("application/binary;charset=" + "UTF-8");
        String fileName = Utils.processFileName(request, "采购订单Excel");
        response.setHeader("Content-disposition", "attachment; filename=" + fileName + ".xlsx");// 组装附件名称和格式
        response.setCharacterEncoding("UTF-8");
        String hql = "采购订单"; // sheet 名称
        List<Map> lm = new ArrayList<Map>();
        for (int i = 0; i < list.size(); i++) {
            Map map = new LinkedHashMap();
            PurchaseOrderVo ov = list.get(i);
            map.put("采购单号", ov.getNo());
            map.put("供应商", ov.getClienteleName());
            map.put("产品名称", ov.getGoodsName());
            map.put("价格", ov.getCurrentPrice());
            map.put("订单金额", ov.getCurrentPrice().multiply(ov.getNumber()));
            map.put("税率", ov.getTaxRatio());
            map.put("实付金额", ov.getActualReceiveTotal());
            map.put("申请金额", ov.getApplyPayTotal());
            map.put("采购数量", ov.getNumber());
            map.put("收货中数量", ov.getNumberReceiving());
            map.put("实收数量", ov.getNumberActualReceive());
            map.put("签章状态", "1".equals(ov.getApplySignature()) ? "申请中" : ("2".equals(ov.getApplySignature()) ? "已签章" : ("未申请签章")));
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            map.put("付款日期", sdf.format(ov.getPayTime()));
            map.put("免费仓储期", sdf.format(ov.getStoreTime()));
            map.put("是否已申请付款", "1".equals(ov.getApplyPay()) ? "已申请付款" : ("2".equals(ov.getApplyPay()) ? "部分申请付款" : ("未申请付款")));
            map.put("供货地", ov.getDeliverPlace());
            map.put("付款状态", "0".equals(ov.getPayStatus()) ? "未付款" : ("1".equals(ov.getPayStatus()) ? "部分付款" : "已付款"));
            map.put("审核状态", "0".equals(ov.getCheckStatus()) ? "未审核" : ("1".equals(ov.getCheckStatus()) ? "审核通过" : "审核未通过"));
            map.put("审核说明", ov.getReason());
            map.put("订单状态", "0".equals(ov.getStatus()) ? "未执行" : ("1".equals(ov.getStatus()) ? "执行中" : ("2".equals(ov.getStatus()) ? "终止执行" : ("3".equals(ov.getStatus()) ? "强制执行完毕" : ("4".equals(ov.getStatus()) ? "执行完毕" : (""))))));
            map.put("下单用户", ov.getUserName());
            map.put("下单时间", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(ov.getCreateAt()));
            map.put("包装规格", ov.getPack());
            map.put("备注", ov.getRemark());
            lm.add(map);
        }
        return exportService.exportExcel(hql, lm, outputStream);
    }


    /**
     * 导出采购应收明细
     *
     * @param arg
     * @param session
     * @return
     */
    @SameUrlData
    @RequestMapping(value = "/exportShouldReceive", method = RequestMethod.GET)
    public OutputStream exportShouldReceive(PurchaseOrderVo arg, HttpSession session, HttpServletResponse response, HttpServletRequest request) throws IOException {
        ListResult lr = query(arg, session, true);
        List<PurchaseOrderVo> list = (List<PurchaseOrderVo>) lr.getList();
        ServletOutputStream outputStream = response.getOutputStream();
        response.setContentType("application/binary;charset=" + "UTF-8");
        String fileName = Utils.processFileName(request, "采购应收明细Excel");
        response.setHeader("Content-disposition", "attachment; filename=" + fileName + ".xlsx");// 组装附件名称和格式
        response.setCharacterEncoding("UTF-8");
        String hql = "采购应收明细"; // sheet 名称
        List<Map> lm = new ArrayList<Map>();
        for (int i = 0; i < list.size(); i++) {
            Map map = new LinkedHashMap();
            PurchaseOrderVo ov = list.get(i);
            map.put("采购单号", ov.getNo());
            map.put("产品", ov.getGoodsName());
            map.put("价格", ov.getCurrentPrice());
            map.put("订单金额", ov.getCurrentPrice().multiply(ov.getNumber()));
            map.put("税率", ov.getTaxRatio());
            map.put("实付金额", ov.getActualReceiveTotal());
            map.put("采购数量", ov.getNumber());
            map.put("实收数量", ov.getNumberActualReceive());
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            map.put("付款日期", sdf.format(ov.getPayTime()));
            map.put("应退金额", ov.getNumberActualReceive().subtract(ov.getCurrentPrice().multiply(ov.getNumberActualReceive())));
            map.put("免费仓储期", sdf.format(ov.getStoreTime()));
            map.put("供货地", ov.getDeliverPlace());
            map.put("供应商", ov.getClienteleName());
            map.put("支付状态", "0".equals(ov.getPayStatus()) ? "未付款" : ("1".equals(ov.getPayStatus()) ? "部分付款" : "已付款"));
            map.put("审核状态", "0".equals(ov.getCheckStatus()) ? "未审核" : ("1".equals(ov.getCheckStatus()) ? "审核通过" : "审核未通过"));
            map.put("原因", ov.getReason());
            map.put("创建用户", ov.getUserName());
            map.put("下单时间", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(ov.getCreateAt()));
            lm.add(map);
        }
        return exportService.exportExcel(hql, lm, outputStream);
    }

    /**
     * 导出采购已收明细
     *
     * @param arg
     * @param session
     * @return
     */
    @SameUrlData
    @RequestMapping(value = "/exportShouldReceived", method = RequestMethod.GET)
    public OutputStream exportShouldReceived(PurchaseOrderVo arg, HttpSession session, HttpServletResponse response, HttpServletRequest request) throws IOException {
        ListResult lr = query(arg, session, true);
        List<PurchaseOrderVo> list = (List<PurchaseOrderVo>) lr.getList();
        ServletOutputStream outputStream = response.getOutputStream();
        response.setContentType("application/binary;charset=" + "UTF-8");
        String fileName = Utils.processFileName(request, "导出采购已收明细Excel");
        response.setHeader("Content-disposition", "attachment; filename=" + fileName + ".xlsx");// 组装附件名称和格式
        response.setCharacterEncoding("UTF-8");
        String hql = "导出采购已收明细"; // sheet 名称
        List<Map> lm = new ArrayList<Map>();
        for (int i = 0; i < list.size(); i++) {
            Map map = new LinkedHashMap();
            PurchaseOrderVo ov = list.get(i);
            map.put("采购单号", ov.getNo());
            map.put("产品", ov.getGoodsName());
            map.put("价格", ov.getCurrentPrice());
            map.put("退款金额", ov.getActualReceiveTotal().subtract(ov.getCurrentPrice().multiply(ov.getNumber())));
            map.put("实付金额", ov.getActualReceiveTotal());
            map.put("采购数量", ov.getNumber());
            map.put("收货中数量", ov.getNumberReceiving());
            map.put("实收数量", ov.getNumberActualReceive());
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            map.put("付款日期", sdf.format(ov.getPayTime()));
            map.put("免费仓储期", sdf.format(ov.getStoreTime()));
            map.put("是否已申请付款", "1".equals(ov.getApplyPay()) ? "已申请付款" : "未申请付款");
            map.put("供货地", ov.getDeliverPlace());
            map.put("供应商", ov.getClienteleName());
            map.put("支付状态", "0".equals(ov.getPayStatus()) ? "未付款" : ("1".equals(ov.getPayStatus()) ? "部分付款" : "已付款"));
            map.put("审核状态", "0".equals(ov.getCheckStatus()) ? "未审核" : ("1".equals(ov.getCheckStatus()) ? "审核通过" : "审核未通过"));
            map.put("原因", ov.getReason());
            map.put("订单状态", "0".equals(ov.getStatus()) ? "未执行" : ("1".equals(ov.getStatus()) ? "执行中" : ("2".equals(ov.getStatus()) ? "终止执行" : ("3".equals(ov.getStatus()) ? "强制执行完毕" : ("4".equals(ov.getStatus()) ? "执行完毕" : (""))))));
            map.put("创建用户", ov.getUserName());
            map.put("下单时间", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(ov.getCreateAt()));
            lm.add(map);
        }
        return exportService.exportExcel(hql, lm, outputStream);
    }
}